package com.mihuo.config;

import com.mihuo.config.quartz.QuartzScheduled;
import org.quartz.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Map;

/**
 * Quartz定时任务配置类
 *
 * 负责自动扫描并注册带有@QuartzScheduled注解的定时任务
 * 相关数据表会自动创建
 * @author mihuo
 * @version 1.0
 * @since 2025/09/30
 */
@Configuration
public class QuartzJobConfig {

    /**
     * Quartz调度器实例，用于管理所有定时任务
     */
    @Resource
    private Scheduler scheduler;

    /**
     * Spring应用上下文，用于获取容器中的Bean实例
     */
    @Resource
    private ApplicationContext applicationContext;

    /**
     * 初始化方法，在Bean创建后自动执行
     * 扫描所有带有@QuartzScheduled注解的Job类并注册到Quartz调度器
     *
     * @throws SchedulerException 当任务注册或调度器启动失败时抛出
     */
    @PostConstruct
    public void registerAnnotatedJobs() throws SchedulerException {
        // 获取所有带有QuartzScheduled注解的Bean
        Map<String, Object> annotatedBeans = applicationContext.getBeansWithAnnotation(QuartzScheduled.class);

        // 遍历并注册每个Job类
        for (Object bean : annotatedBeans.values()) {
            if (bean instanceof Job) {
                registerJob((Class<? extends Job>) bean.getClass());
            }
        }

        // 确保调度器已启动
        if (!scheduler.isStarted()) {
            scheduler.start();
        }
    }

    /**
     * 注册单个定时任务到Quartz调度器
     *
     * @param jobClass 实现了Job接口的任务类
     * @throws SchedulerException 当任务已存在或注册过程中发生错误时抛出
     */
    private void registerJob(Class<? extends Job> jobClass) throws SchedulerException {
        QuartzScheduled annotation = jobClass.getAnnotation(QuartzScheduled.class);
        if (annotation != null) {
            // 处理任务名称和组名的默认值
            String jobName = annotation.jobName().isEmpty() ?
                    jobClass.getSimpleName() : annotation.jobName();
            String groupName = annotation.groupName().isEmpty() ?
                    "defaultGroup" : annotation.groupName();

            // 创建JobDetail实例
            JobDetail jobDetail = JobBuilder.newJob(jobClass)
                    .withIdentity(jobName, groupName)
                    .usingJobData("taskName", jobName)
                    .storeDurably()
                    .build();

            // 创建触发器
            Trigger trigger = TriggerBuilder.newTrigger()
                    .forJob(jobDetail)
                    .withIdentity(jobName + "Trigger", groupName)
                    .withSchedule(CronScheduleBuilder.cronSchedule(annotation.cron()))
                    .build();

            // 避免重复注册
            if (!scheduler.checkExists(jobDetail.getKey())) {
                scheduler.scheduleJob(jobDetail, trigger);
            }
        }
    }
}